package perf.graph;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

import org.apache.commons.collections15.functors.ConstantTransformer;

import perf.data.Run;
import perf.store.StoreManager;
import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.SparseGraph;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.VisualizationImageServer;
import edu.uci.ics.jung.visualization.VisualizationServer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.GradientVertexRenderer;
import edu.uci.ics.jung.visualization.renderers.VertexLabelAsShapeRenderer;

public class test {

	private static final boolean GEN_IMG = false;
	private static final boolean SHOW_IMG = false;
	
	private static Dimension size = new Dimension(500, 600);
	private static Point2D centre = new Point2D.Double(size.getWidth()/2, size.getHeight()/2);

	public static void main(String[] args) {
		try {

			SparseGraph<Vertex, Edge> sg = getGraph();

			Layout<Vertex, Edge> layout = new ISOMLayout<Vertex, Edge>(sg);

			// sets the initial size of the space
			layout.setSize(size);

			if (GEN_IMG) {

				VisualizationViewer<Vertex, Edge> vv = new VisualizationViewer<Vertex, Edge>(
						layout);

				vv.setPreferredSize(size); // Sets the viewing area size

				vv.setVertexToolTipTransformer(new ToStringLabeller<Vertex>());
				vv.setEdgeToolTipTransformer(new ToStringLabeller<Edge>());

				genericSetup(vv);
				show(vv);
			} else {
/*
				VisualizationImageServer<Vertex, Edge> vis 
					= new VisualizationImageServer<Vertex, Edge>(layout, size);
				vis.setPreferredSize(size);
				
				genericSetup(vis);
*/
				VisualizationImageServer<Vertex, Edge> vis 
					= VisualizationGenerator.getImageServer(sg, size );
				
				write(vis);
				if (SHOW_IMG) {
					showImage(vis);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static void showImage(VisualizationImageServer<Vertex, Edge> vis) {
		Image im = vis.getImage(centre, size);

		// create a frame to hold the graph
		final JFrame frame = new JFrame();
		Container content = frame.getContentPane();
		Icon icon = new ImageIcon(im);
		JLabel label = new JLabel(icon);

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		content.add(label);
		frame.pack();
		frame.setVisible(true);
	}

	@SuppressWarnings("unchecked")
	public static void genericSetup(VisualizationServer<Vertex, Edge> vs) {

		VertexLabelAsShapeRenderer<Vertex, Edge> vlasr 
			= new VertexLabelAsShapeRenderer<Vertex, Edge>(vs.getRenderContext());

		// customize the render context
		vs.getRenderContext().setVertexLabelTransformer( new ToStringLabeller<Vertex>() );
		
/*		// this chains together Transformers so that the html tags
				// are prepended to the toString method output
				new ChainedTransformer<Vertex, Vertex>(new Transformer[] {
						new ToStringLabeller<Vertex>(),
						new Transformer<Vertex, Vertex>() {
							public Vertex transform(Vertex input) {
								return "<html><center>Vertex<p>" + input;
							}
						} }));*/

		vs.getRenderContext().setVertexShapeTransformer(vlasr);
		vs.getRenderContext().setEdgeDrawPaintTransformer(
				new ConstantTransformer(Color.blue));
		vs.getRenderContext().setEdgeStrokeTransformer(
				new ConstantTransformer(new BasicStroke(2.5f)));

		// customize the renderer
		vs.getRenderer().setVertexRenderer(
				new GradientVertexRenderer<Vertex, Edge>(Color.gray,
						Color.white, true));
		vs.getRenderer().setVertexLabelRenderer(vlasr);
	}

	public static SparseGraph<Vertex, Edge> getGraph() {
		StoreManager sm = new StoreManager();
		sm.contextInitialized(null);
		
		List<Run> runs = StoreManager.store().list().runs();
		
		return GraphGenerator.getGraph( runs.get(0) );
		/*
		SparseGraph<String, Integer> sg = new SparseGraph<String, Integer>();
		sg.addVertex("node number one");
		sg.addVertex("node number two");
		sg.addVertex("node number three");
		sg.addEdge(1, "node number one", "node number two");
		sg.addEdge(2, "node number two", "node number three");
		sg.addEdge(3, "node number three", "node number one");
		return sg;
		*/
	}

	public static void write(VisualizationImageServer<Vertex, Edge> vs) {
		BufferedImage bi = imageToBufferedImage(vs.getImage(centre, size), size.width,
				size.height);
		File pngfile = new File("/home/hakesson/workspace/PerfEct/out.png");

		try {
			ImageIO.write(bi, "PNG", pngfile);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static BufferedImage imageToBufferedImage(Image image, int width,
			int height) {
		BufferedImage dest = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = dest.createGraphics();
		g2.drawImage(image, 0, 0, null);
		g2.dispose();
		return dest;
	}

	public static void show(BasicVisualizationServer<Vertex, Edge> vv) {
		JFrame frame = new JFrame("Simple Graph View");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(vv);
		frame.pack();
		frame.setVisible(true);
	}
}
